package uz.rt.dicom.data;

import uz.rt.dicom.ValueMultiplicity;
import uz.rt.dicom.ValueRepresentation;
import uz.rt.dicom.io.DicomInputStream;
import uz.rt.dicom.tag.DicomTag;

import java.io.IOException;

/**
 * Interface defining the functions needed for a Dicom data element.
 * Dicom data elements contain:
 * <ul>
 * <li>A dicom tag</li>
 * <li>Value length defined either in bytes or characters</li>
 * <li>One or more values stored sequentially. Separation of the values is done based on a fixed byte level or a
 * delimiter.</li>
 * </ul>
 */
public interface IDataElement
{
// -------------------------- OTHER METHODS --------------------------

    /**
     * Get the delimiter separating multiple data fields in a dicom value.
     *
     * @return Delimiter separating multiple data fields in a dicom value.
     */
    public String getDelimiter();

    /**
     * Get the number of data fields in a dicom element.
     *
     * @return The number of data fields in a dicom element.
     */
    public int getLength();

    /**
     * Get the maximum length of the a dicom value either defined in bytes or characters.
     *
     * @return Maximum length of the a dicom value either defined in bytes or characters.
     */
    public int getMaxLength();

    /**
     * Get the dicom tag
     *
     * @return Dicom tag
     */
    public DicomTag getTag();

    /**
     * Get the value representation of the data element
     *
     * @return Value representation of the data element
     */
    public byte[] getVR();

    /**
     * Get the value representation of the data element
     *
     * @return Value representation of the data element
     */
    public ValueRepresentation getValueRepresentation();

    /**
     * Get the value multiplicity range for a dicom element.
     *
     * @return The value multiplicity range for a dicom element.
     */
    public ValueMultiplicity getVm();

    /**
     * Is the byte length of the data field fixed?
     *
     * @return True if the byte length is fixed
     */
    public boolean isLengthFixed();


    /**
     * Read the dicom information from the dicom input stream.
     * The position in the stream should be just after the value representation and ready to read the element value.
     * The
     * amount of data that will be read depends on the length parameters in the dicom element classes.
     *
     * @param dicomInputStream Dicom input stream from which the data will be read
     * @param length           in bytes that needs to be read from the dicom stream
     * @throws java.io.IOException If an IO error occurs.
     */
    public void read(DicomInputStream dicomInputStream, int length) throws IOException;

    /**
     * Set the delimiter separating multiple data fields in a dicom value.
     *
     * @param delimiter Delimiter separating multiple data fields in a dicom value.
     */
    public void setDelimiter(String delimiter);

    /**
     * Set the dicom tag
     *
     * @param tag Dicom tag
     */
    public void setTag(DicomTag tag);

    /**
     * Set the value representation of the data element
     *
     * @param vr Value representation of the data element
     */
    public void setValueRepresentation(ValueRepresentation vr);
}
